package com.example.student.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.student.entity.SysRole;
import com.example.student.entity.SysRoleMenu;
import com.example.student.exception.BusinessException;
import com.example.student.mapper.SysRoleMapper;
import com.example.student.mapper.SysRoleMenuMapper;
import com.example.student.model.PageResult;
import com.example.student.service.RoleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private SysRoleMapper roleMapper;

    @Resource
    private SysRoleMenuMapper roleMenuMapper;

    @Override
    public PageResult<SysRole> getRoleList(Integer page, Integer pageSize, String roleName, String roleCode) {
        Page<SysRole> pageParam = new Page<>(page, pageSize);
        
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(roleName), SysRole::getRoleName, roleName)
                .like(StringUtils.isNotBlank(roleCode), SysRole::getRoleCode, roleCode)
                .orderByAsc(SysRole::getId);
        
        Page<SysRole> rolePage = roleMapper.selectPage(pageParam, queryWrapper);
        
        PageResult<SysRole> pageResult = new PageResult<>();
        pageResult.setTotal(rolePage.getTotal());
        pageResult.setList(rolePage.getRecords());
        pageResult.setPageNum(page);
        pageResult.setPageSize(pageSize);
        
        return pageResult;
    }

    @Override
    public List<SysRole> getAllRoles() {
        return roleMapper.selectList(null);
    }

    @Override
    public List<SysRole> getAvailableRoles() {
        // 查询状态为启用的角色
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getStatus, 1)
                    .orderByAsc(SysRole::getId);
        return roleMapper.selectList(queryWrapper);
    }

    @Override
    public SysRole getRoleById(Long id) {
        return roleMapper.selectById(id);
    }

    @Override
    public void addRole(SysRole role) {
        // 检查角色编码是否已存在
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleCode, role.getRoleCode());
        if (roleMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException("角色编码已存在");
        }
        
        // 设置默认状态为启用
        if (role.getStatus() == null) {
            role.setStatus(1);
        }
        
        roleMapper.insert(role);
    }

    @Override
    public void updateRole(SysRole role) {
        // 检查角色是否存在
        SysRole existingRole = roleMapper.selectById(role.getId());
        if (existingRole == null) {
            throw new BusinessException("角色不存在");
        }
        
        roleMapper.updateById(role);
    }

    @Override
    public void deleteRole(Long id) {
        // 检查角色是否存在
        SysRole role = roleMapper.selectById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        // 检查是否为系统内置角色
        if ("ROLE_ADMIN".equals(role.getRoleCode())) {
            throw new BusinessException("系统内置角色不能删除");
        }
        
        // 删除角色
        roleMapper.deleteById(id);
        
        // 删除角色关联的菜单权限
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, id);
        roleMenuMapper.delete(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignMenus(Long roleId, List<Long> menuIds) {
        // 检查角色是否存在
        SysRole role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        // 删除原有的菜单权限
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, roleId);
        roleMenuMapper.delete(queryWrapper);
        
        // 添加新的菜单权限
        if (menuIds != null && !menuIds.isEmpty()) {
            List<SysRoleMenu> roleMenuList = menuIds.stream().map(menuId -> {
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                return roleMenu;
            }).collect(Collectors.toList());
            
            for (SysRoleMenu roleMenu : roleMenuList) {
                roleMenuMapper.insert(roleMenu);
            }
        }
    }

    @Override
    public List<SysRole> getRolesByUserId(Long userId) {
        return roleMapper.selectRolesByUserId(userId);
    }

    @Override
    public List<Long> getMenuIdsByRoleId(Long roleId) {
        // 检查角色是否存在
        SysRole role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        // 查询角色拥有的菜单ID列表
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, roleId);
        List<SysRoleMenu> roleMenuList = roleMenuMapper.selectList(queryWrapper);
        
        // 提取菜单ID
        return roleMenuList.stream()
                .map(SysRoleMenu::getMenuId)
                .collect(Collectors.toList());
    }
} 